using System;
using System.Collections;
using System.Security.Principal;
using System.Web;
using System.Reflection;
using System.Data;

using Castle.Facilities.NHibernateIntegration;
using Castle.Services.Transaction;

using NHibernate;

using NetBpm.Util.Client;
using NetBpm.Workflow.Organisation.EComp;
using NetBpm.Workflow.Organisation;
using NetBpm.Workflow.Delegation;
using NetBpm.Workflow.Definition;
using NetBpm.Workflow.Definition.EComp;
using NetBpm.Workflow.Execution;
using NetBpm.Workflow.Execution.EComp;
using NetBpm.Workflow.Definition.Attr;
using NetBpm.Workflow.Log.EComp;

using BEGDC.Utility.ExceptionManagement;
//using BEGDC.CC.BL.Email;
using BEGDC.Utility.Castle;
//using BEGDC.CC.BL.Common;
//using BEGDC.CC.BL;

namespace BEGDC.CC.BL.Workflow
{
	/// <summary>
	/// Summary description for NBPMExecuteService.
	/// </summary>
	[Transactional]
	public class NBPMExecuteService : IExecute
	{
		private ISessionManager _sessionManager;

		/// <summary>
		/// 
		/// </summary>
		/// <param name="sessionManager"></param>
		public NBPMExecuteService(ISessionManager sessionManager)
		{
			this._sessionManager = sessionManager;
		}

		private const string NEXT_TRANSITION = "NextTransition";
		#region IExecute Members
		/// <summary>
		/// Start an new cq process
		/// </summary>
		/// <returns>process instance flow id</returns>
		[Transaction(TransactionMode.Requires)]
		public long StartProcess()
		{
			return this.StartProcess(Configuration.PDCVID);
		}

//		/// <summary>
//		/// Start an new cr process
//		/// </summary>
//		/// <returns>process instance flow id</returns>
//		[Transaction(TransactionMode.Requires)]
//		public long StartCRProcess(System.Collections.Hashtable attributes)
//		{
//			IExecutionSessionLocal executionComponent = null;
//			try
//			{
//				
//				executionComponent = ServiceLocator.Instance.GetService(typeof (IExecutionSessionLocal)) as IExecutionSessionLocal;
//				IProcessInstance processInstance = executionComponent.StartProcessInstance(Configuration.CRPDID,attributes);
//				return processInstance.RootFlow.Id;
//			}
//			catch(Exception ex)
//			{
//				throw new GDCException(WorkflowErrorCode.EXEC_START, "Start CR Process error.", ex);
//			}
//			finally
//			{
//				ServiceLocator.Instance.Release(executionComponent);
//			}
//		}
//

//		/// <summary>
//		/// Start a new Technical Support process
//		/// </summary>
//		/// <returns></returns>
//		[Transaction(TransactionMode.Requires)]
//		public long StartTSProcess()
//		{
//			IExecutionSessionLocal executionComponent = null;
//			try
//			{
//				executionComponent = ServiceLocator.Instance.GetService(typeof(IExecutionSessionLocal)) as IExecutionSessionLocal;
//				IProcessInstance processInstance = executionComponent.StartProcessInstance(Configuration.TSPDID);
//				return processInstance.RootFlow.Id;
//			}
//			catch(Exception ex)
//			{
//				throw new GDCException(WorkflowErrorCode.EXEC_START, "Start TS Process error.", ex);
//			}
//			finally
//			{
//				ServiceLocator.Instance.Release(executionComponent);
//			}
//
//		}
//

		/// <summary>
		/// Start an new process by specified definition id
		/// </summary>
		/// <param name="pdID">definition id</param>
		/// <returns>process instance flow id</returns>
		[Transaction(TransactionMode.Requires)]
		public long StartProcess(long pdID)
		{
			IExecutionSessionLocal executionComponent = null;
			try
			{
				
				executionComponent = ServiceLocator.Instance.GetService(typeof (IExecutionSessionLocal)) as IExecutionSessionLocal;
				IProcessInstance processInstance = executionComponent.StartProcessInstance(pdID);
				return processInstance.RootFlow.Id;
			}
			catch(Exception ex)
			{
				throw new GDCException(WorkflowErrorCode.EXEC_START, "Start CQ Process error.", ex);
			}
			finally
			{
				ServiceLocator.Instance.Release(executionComponent);
			}
		}

		/// <summary>
		/// Execute the workflow activity by specified flow ID
		/// </summary>
		/// <param name="flowID">Flow ID</param>
		[Transaction(TransactionMode.Requires)]
		public void PerformActivity(long flowID)
		{
			this.Perform(flowID, null);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="flowID"></param>
		[Transaction(TransactionMode.Requires)]
		public void PerformTSActivity(long flowID)
		{
			PerformTS(flowID, null);
		}
		
		/// <summary>
		/// 
		/// </summary>
		/// <param name="flowID"></param>
		/// <param name="nextTransition"></param>
		public void PerformTSActivity(long flowID, string nextTransition)
		{
			IDictionary attributes = new Hashtable();				
			attributes.Add(NEXT_TRANSITION, nextTransition);
			PerformTS( flowID, attributes );
		}
		/// <summary>
		/// Execute the decision activity by specified flow ID
		/// </summary>
		/// <param name="flowID">Flow ID</param>
		/// <param name="isYes">Decision Result</param>
		[Transaction(TransactionMode.Requires)]
		public void PerformDecision(long flowID, bool isYes)
		{
			IDictionary attributes = new Hashtable();				
			attributes.Add(NEXT_TRANSITION, isYes.ToString());
			this.Perform(flowID, attributes);
		}

		/// <summary>
		/// Execute the activity by specified flow ID and transition.
		/// </summary>
		/// <param name="flowID">Flow ID</param>
		/// <param name="nextTransition">Next Transition</param>
		[Transaction(TransactionMode.Requires)]
		public void PerformActivity(long flowID, string nextTransition)
		{
			IDictionary attributes = new Hashtable();				
			attributes.Add(NEXT_TRANSITION, nextTransition);
			this.Perform(flowID, attributes);
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="flowID"></param>
		/// <returns></returns>
//		[Transaction(TransactionMode.Requires)]
//		public CODMActivityState GetPreviousActivityState(long flowID)
//		{
//			IExecutionSessionLocal executionComponent = null;
//			try
//			{
//				executionComponent = ServiceLocator.Instance.GetService(typeof (IExecutionSessionLocal)) as IExecutionSessionLocal;	
//				
//				IList flows = null;
//				IActivityState state = executionComponent.GetPreviousActivityState(flowID);
//
//				CODMActivityState cqstate = new CODMActivityState();
//				cqstate.StateKey = state.Name;
//				cqstate.Actor = state.ActorRoleName;
//				return cqstate;
//			}
//			catch(Exception ex)
//			{
//				throw new GDCException(WorkflowErrorCode.EXEC_DRAWBACK, "Drawback flow("+flowID.ToString()+") error.", ex);
//			}
//			finally
//			{
//				ServiceLocator.Instance.Release(executionComponent);
//			}
//
//		}		
		
		/// <summary>
		/// 
		/// </summary>
		/// <param name="flowId"></param>
		/// <param name="actorId"></param>
		[Transaction(TransactionMode.Requires)]
		public void DelegateActivity(Int64 flowId, string actorId)
		{
			IExecutionSessionLocal executionComponent = null;
			try
			{
				executionComponent.DelegateActivity(flowId, actorId);
			}
			catch(Exception ex)
			{
				throw new GDCException(WorkflowErrorCode.EXEC_DELEGATE, "Delegate flow("+flowId.ToString()+") error.", ex);
			}
			finally
			{
				ServiceLocator.Instance.Release(executionComponent);
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="flowID"></param>
		[Transaction(TransactionMode.Requires)]
		public void DrawbackActivity(long flowID)
		{
			IExecutionSessionLocal executionComponent = null;
			try
			{
				executionComponent = ServiceLocator.Instance.GetService(typeof (IExecutionSessionLocal)) as IExecutionSessionLocal;	
				
				IList flows = null;
				flows = executionComponent.DrawbackActivity(flowID, null, null);

				if (flows.Count > 0)
				{
					IFlow flow = (IFlow)flows[0];
					string status = flow.Node.Name;
					string owner = "";
					Type curtype = flow.Node.GetType();
					Type endtype = typeof(NetBpm.Workflow.Definition.Impl.EndStateImpl);
					if (curtype.Equals(endtype) || curtype.IsSubclassOf(endtype))
						owner = "N/A";
					else
						owner = flow.GetActor().Name;

					string statusflag = BEGDC.CC.BL.Common.SysDicItem.ProjectStatusFlag.DRAWBACK;
					//Update Project Status
					using(ISession session = _sessionManager.OpenSession())
					{
						try
						{
							string sql = "Update Project Set ProjectStatus='"+status+"', CurrentOwner='"+owner+"', StatusFlag='"+statusflag+"' Where NBPMFlow="+flowID.ToString();
							BEGDC.Utility.NHibernate.NHibernateUtil.ExecuteNonQuery(session, sql);

							sql = "Update Change Set ChangeStatus='"+status+"' Where NBPMFlow="+flowID.ToString();
							BEGDC.Utility.NHibernate.NHibernateUtil.ExecuteNonQuery(session, sql);							
						}
						catch(Exception exp)
						{
							throw exp;
						}
						finally
						{
							session.Close();
						}						
					}
				}

//				IEmail email = AppContainer.Instance[ServiceConst.EmailService] as IEmail;
//				email.Send(flowID, "Workflow_Drawback");
			}
			catch(Exception ex)
			{
				throw new GDCException(WorkflowErrorCode.EXEC_DRAWBACK, "Drawback flow("+flowID.ToString()+") error.", ex);
			}
			finally
			{
				ServiceLocator.Instance.Release(executionComponent);
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="flowID"></param>
		/// <param name="stateID"></param>
		public void MoveFlowState(long flowID, long stateID)
		{
			IExecutionSessionLocal executionComponent = null;
			try
			{
				executionComponent = ServiceLocator.Instance.GetService(typeof (IExecutionSessionLocal)) as IExecutionSessionLocal;	
				
				IList flows = null;
				flows = executionComponent.MoveFlowState(flowID, stateID);
			}
			catch(Exception ex)
			{
				throw new GDCException(WorkflowErrorCode.EXEC_MOVE, "Move flow("+flowID.ToString()+") error.", ex);
			}
			finally
			{
				ServiceLocator.Instance.Release(executionComponent);
			}
		}

		
//		[Transaction(TransactionMode.Requires)]
//		public void MoveFlowState( long flowID, string stateKey, string statusFlag)
//		{
//			ProcessStateList states = Configuration.ProcessDefinition;
//			for(int i=0; i < states.Count; i++)
//			{
//				ProcessState state = states[i];
//				for(int j=0; j < state.ChildrenStates.Count; j++)
//				{
//					ProcessState chr = state.ChildrenStates[j];
//					if (chr.Key == stateKey)
//					{
//						this.MoveFlowState(flowID, chr.ID, statusFlag);
//						return;
//					}
//				}
//			}			
//		}
//

		/// <summary>
		/// 
		/// </summary>
		/// <param name="flowID"></param>
		/// <param name="stateID"></param>
		public void MoveFlowState( long flowID, long stateID, string statusFlag)
		{
			IExecutionSessionLocal executionComponent = null;
			try
			{
				executionComponent = ServiceLocator.Instance.GetService(typeof (IExecutionSessionLocal)) as IExecutionSessionLocal;	
				
				IList flows = null;
				flows = executionComponent.MoveFlowState(flowID, stateID);

				if (flows.Count > 0)
				{
					IFlow flow = (IFlow)flows[0];
					string status = flow.Node.Name;
					string owner = "";
					Type curtype = flow.Node.GetType();
					Type endtype = typeof(NetBpm.Workflow.Definition.Impl.EndStateImpl);
					if (curtype.Equals(endtype) || curtype.IsSubclassOf(endtype))
						owner = "N/A";
					else
						owner = flow.GetActor().Name;
					//Update Project Status					

					using(ISession session = _sessionManager.OpenSession())
					{
						try
						{							
								string sql = "Update Project Set ProjectStatus='"+status+"', CurrentOwner='"+owner+"', StatusFlag='"+statusFlag+"' Where NBPMFlow="+flowID.ToString();
								BEGDC.Utility.NHibernate.NHibernateUtil.ExecuteNonQuery(session, sql);
						}
						catch(Exception exp)
						{
							throw exp;
						}
						finally
						{
							session.Close();
						}						
					}
				}
			}
			catch(Exception ex)
			{
				throw new GDCException(WorkflowErrorCode.EXEC_MOVE, "Move flow("+flowID.ToString()+") error.", ex);
			}
			finally
			{
				ServiceLocator.Instance.Release(executionComponent);
			}
		}


		/// <summary>
		/// 
		/// </summary>
		/// <param name="flowID"></param>
		/// <param name="stateKey"></param>
		[Transaction(TransactionMode.Requires)]
		public void MoveFlowState(long flowID, string stateKey, string type)
		{
			ProcessStateList states = Configuration.GetProcessStateList(type);
			for(int i=0; i < states.Count; i++)
			{
				ProcessState state = states[i];
				for(int j=0; j < state.ChildrenStates.Count; j++)
				{
					ProcessState chr = state.ChildrenStates[j];
					if (chr.Key == stateKey)
					{
						this.MoveFlowState(flowID, chr.ID);
						return;
					}
				}
			}			
		}

//		/// <summary>
//		/// Jovi.Chen 1/24/2007 update For Ask For More feature
//		/// </summary>
//		/// <param name="flowID"></param>
//		/// <param name="stateID"></param>
//		public void MoveAskForMoreState(Project project, Employee employee, string StateKey, string comment)
//		{
//			IExecutionSessionLocal executionComponent = null;
//			try
//			{
//				//****************************
//				//Get State ID
//				long stateID = 0;
//				ProcessStateList states = Configuration.ProcessDefinition;
//				for(int i=0; i < states.Count; i++)
//				{
//					ProcessState state = states[i];
//					for(int j=0; j < state.ChildrenStates.Count; j++)
//					{
//						ProcessState chr = state.ChildrenStates[j];
//						if (chr.Key == StateKey)
//						{
//							stateID = chr.ID;
//						}
//					}
//				}
//				//****************************
//				executionComponent = ServiceLocator.Instance.GetService(typeof (IExecutionSessionLocal)) as IExecutionSessionLocal;	
//				
//				IList flows = null;
//				flows = executionComponent.MoveFlowState(project.NBPMFlow, stateID);
//
//				if (flows.Count > 0)
//				{
//					IFlow flow = (IFlow)flows[0];
//					string status = flow.Node.Name;
//					string owner = "";
//					Type curtype = flow.Node.GetType();
//					Type endtype = typeof(NetBpm.Workflow.Definition.Impl.EndStateImpl);
//					if (curtype.Equals(endtype) || curtype.IsSubclassOf(endtype))
//						owner = "N/A";
//					else
//						owner = flow.GetActor().Name;
//					//Update Project Status
//					string statusflag = BEGDC.CC.BL.Common.SysDicItem.ProjectStatusFlag.AskForMore;
//
//					
//					using(ISession session = _sessionManager.OpenSession())
//					{
//						try
//						{
//							//********************************************
//							// Do Action Log
//							Common.Log.ActionLogService logsrv = new Common.Log.ActionLogService();
//
//							ActionLog log = new ActionLog();
//							log.Project = project;
//							log.Project.Id = project.Id;
//							log.Owner = employee;
//							log.Owner.Id = employee.Id;
//							//log.BusinessUnit = Convert.ToString(client.BG) + "/" + Convert.ToString(client.BU);
//							log.BusinessUnit = "";
//							log.Operation = project.ProjectStatus;
//							log.Comment = "AskForMore";
//			
//							log.LogTime = DateTime.Now;
//							logsrv.Add( log, session );
//							//********************************************
//
//							if (status != BEGDC.CC.BL.Workflow.WorkTransition.End)
//							{
//								string sql = "Update Project Set ProjectStatus='"+status+"', CurrentOwner='"+owner+"', StatusFlag='"+statusflag+"' Where NBPMFlow="+project.NBPMFlow.ToString();
//								BEGDC.Utility.NHibernate.NHibernateUtil.ExecuteNonQuery(session, sql);
//
//								//sql = "Update Change Set ChangeStatus='"+status+"' Where NBPMFlow="+flowID.ToString();
//								//BEGDC.Utility.NHibernate.NHibernateUtil.ExecuteNonQuery(session, sql);
//							}
//							else
//							{
//								statusflag = BEGDC.CC.BL.Common.SysDicItem.ProjectStatusFlag.CANCEL;
//						
//								string sql = "Update Project Set ProjectStatus='"+status+"', CurrentOwner='"+owner+"',StatusFlag='"+statusflag+"',EndTime='"+DateTime.Now.ToString()+"' Where NBPMFlow="+project.NBPMFlow.ToString();
//								BEGDC.Utility.NHibernate.NHibernateUtil.ExecuteNonQuery(session, sql);
//
//								//sql = "Update Change Set ChangeStatus='"+status+"',EndTime='"+DateTime.Now.ToString()+"' Where NBPMFlow="+flowID.ToString();
//								//BEGDC.Utility.NHibernate.NHibernateUtil.ExecuteNonQuery(session, sql);
//							}
//
//							//update Jovi.Chen 2007/3/2
//							ReviewLog reviewlog = new ReviewLog();
//
//							reviewlog.FlowStep = StateKey;
//							//log.Query2Step = QueryOption;
//							reviewlog.LogTime = DateTime.Now;
//							reviewlog.Owner = employee;
//							//reviewlog.Owner.Id = ci.UserId;
//
//							reviewlog.Project = project;				
//							//reviewlog.Project.Id = this.ProjectId;
//							//reviewlog.Id = this.CommentId;
//							reviewlog.Comment = comment.Trim();
//
//							BEGDC.CC.BL.QualFlow.CommonQualService.SubmitComment( session, reviewlog );
//							//************************
//						}
//						catch(Exception exp)
//						{
//							throw exp;
//						}
//						finally
//						{
//							session.Close();
//						}						
//					}
//				}
//			}
//			catch(Exception ex)
//			{
//				throw new GDCException(WorkflowErrorCode.EXEC_MOVE, "Move flow("+project.NBPMFlow.ToString()+") error.", ex);
//			}
//			finally
//			{
//				ServiceLocator.Instance.Release(executionComponent);
//			}
//		}


//		/// <summary>
//		/// Jovi.Chen 1/24/2007 update For Ask For More feature
//		/// </summary>
//		/// <param name="project"></param>
//		public void FinishAskForMoreState(Project project)
//		{
//			IExecutionSessionLocal executionComponent = null;
//			try
//			{
//				using(ISession session = _sessionManager.OpenSession())
//				{
//				//****************************
//				// Get State From ActionLog
//				string StateKey = "";
//				IList list = session.Find("From ActionLog as al where al.Project.Id="+project.Id+" and al.Comment='"+BEGDC.CC.BL.Common.SysDicItem.ProjectStatusFlag.AskForMore+"' Order by al.Id desc");
//				if(list!=null&&list.Count>0)
//				{
//					ActionLog actionlog = list[0] as ActionLog;
//                    StateKey = actionlog.Operation;
//				}
//				else
//				{
//					return;
//				}
//				//****************************
//				//Get State ID
//				long stateID = 0;
//				ProcessStateList states = Configuration.ProcessDefinition;
//				for(int i=0; i < states.Count; i++)
//				{
//					ProcessState state = states[i];
//					for(int j=0; j < state.ChildrenStates.Count; j++)
//					{
//						ProcessState chr = state.ChildrenStates[j];
//						if (chr.Key == StateKey)
//						{
//							stateID = chr.ID;
//						}
//					}
//				}
//				//****************************
//				executionComponent = ServiceLocator.Instance.GetService(typeof (IExecutionSessionLocal)) as IExecutionSessionLocal;	
//				
//				IList flows = null;
//				flows = executionComponent.MoveFlowState(project.NBPMFlow, stateID);
//
//				if (flows.Count > 0)
//				{
//					IFlow flow = (IFlow)flows[0];
//					string status = flow.Node.Name;
//					string owner = "";
//					Type curtype = flow.Node.GetType();
//					Type endtype = typeof(NetBpm.Workflow.Definition.Impl.EndStateImpl);
//					if (curtype.Equals(endtype) || curtype.IsSubclassOf(endtype))
//						owner = "N/A";
//					else
//						owner = flow.GetActor().Name;
//					//Update Project Status
//					string statusflag = BEGDC.CC.BL.Common.SysDicItem.ProjectStatusFlag.NORMAL;
//
//					
//						try
//						{
//
//							if (status != BEGDC.CC.BL.Workflow.WorkTransition.End)
//							{
//								string sql = "Update Project Set ProjectStatus='"+status+"', CurrentOwner='"+owner+"', StatusFlag='"+statusflag+"' Where NBPMFlow="+project.NBPMFlow.ToString();
//								BEGDC.Utility.NHibernate.NHibernateUtil.ExecuteNonQuery(session, sql);
//
//								//sql = "Update Change Set ChangeStatus='"+status+"' Where NBPMFlow="+flowID.ToString();
//								//BEGDC.Utility.NHibernate.NHibernateUtil.ExecuteNonQuery(session, sql);
//							}
//							else
//							{
//								statusflag = BEGDC.CC.BL.Common.SysDicItem.ProjectStatusFlag.CANCEL;
//						
//								string sql = "Update Project Set ProjectStatus='"+status+"', CurrentOwner='"+owner+"',StatusFlag='"+statusflag+"',EndTime='"+DateTime.Now.ToString()+"' Where NBPMFlow="+project.NBPMFlow.ToString();
//								BEGDC.Utility.NHibernate.NHibernateUtil.ExecuteNonQuery(session, sql);
//
//								//sql = "Update Change Set ChangeStatus='"+status+"',EndTime='"+DateTime.Now.ToString()+"' Where NBPMFlow="+flowID.ToString();
//								//BEGDC.Utility.NHibernate.NHibernateUtil.ExecuteNonQuery(session, sql);
//							}
//						}
//						catch(Exception exp)
//						{
//							throw exp;
//						}
//						finally
//						{
//							session.Close();
//						}						
//					}
//				}
//			}
//			catch(Exception ex)
//			{
//				throw new GDCException(WorkflowErrorCode.EXEC_MOVE, "Move flow("+project.NBPMFlow.ToString()+") error.", ex);
//			}
//			finally
//			{
//				ServiceLocator.Instance.Release(executionComponent);
//			}
//		}
//

		/// <summary>
		/// 
		/// </summary>
		/// <param name="flowID"></param>
		/// <param name="stateID"></param>
		[Transaction(TransactionMode.Requires)]
		public void QueryActiity(long flowID, long stateID)
		{
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="flowID"></param>
		/// <param name="stateKey"></param>
		[Transaction(TransactionMode.Requires)]
		public void QueryActiity(long flowID, string stateKey)
		{
//			ProcessStateList states = Configuration.ProcessDefinition;
//			for(int i=0; i < states.Count; i++)
//			{
//				ProcessState state = states[i];
//				for(int j=0; j < state.ChildrenStates.Count; j++)
//				{
//					ProcessState chr = state.ChildrenStates[j];
//					if (chr.Key == stateKey)
//					{
//						this.QueryActiity(flowID, chr.ID);
//						return;
//					}
//				}
//			}
		}
		

		/// <summary>
		/// 
		/// </summary>
		/// <param name="flowID"></param>
		[Transaction(TransactionMode.Requires)]
		public void FinishQuery(long flowID)
		{

		}

		[Transaction(TransactionMode.Requires)]
		public void CancelFlow(long flowID)
		{
			IExecutionSessionLocal executionComponent = null;
			try
			{
				executionComponent = ServiceLocator.Instance.GetService(typeof (IExecutionSessionLocal)) as IExecutionSessionLocal;					
				string statusflag = BEGDC.CC.BL.Common.SysDicItem.ProjectStatusFlag.CANCEL;				
				executionComponent.CancelFlow(flowID);				
				string status = BEGDC.CC.BL.Workflow.WorkTransition.End;
				string owner = "N/A";				

				//Update Project Status
				using(ISession session = _sessionManager.OpenSession())
				{
					try
					{
						string sql = "Update Project Set ProjectStatus='"+status+"', CurrentOwner='"+owner+"',StatusFlag='"+statusflag+"',EndTime='"+DateTime.Now.ToString()+"' Where NBPMFlow="+flowID.ToString();
						BEGDC.Utility.NHibernate.NHibernateUtil.ExecuteNonQuery(session, sql);

						sql = "Update Change Set ChangeStatus='"+status+"',EndTime='"+DateTime.Now.ToString()+"' Where NBPMFlow="+flowID.ToString();
						BEGDC.Utility.NHibernate.NHibernateUtil.ExecuteNonQuery(session, sql);						
					}
					catch(Exception exp)
					{
						throw exp;
					}
					finally
					{
						session.Close();
					}						
				}
				
			}
			catch(Exception ex)
			{
				throw new GDCException(WorkflowErrorCode.EXEC_PERFORM, "Execute flow("+flowID.ToString()+") error.", ex);
			}
			finally
			{
				ServiceLocator.Instance.Release(executionComponent);
			}
		}
		

		/// <summary>
		/// 
		/// </summary>
		/// <returns></returns>
		[Transaction(TransactionMode.Requires)]
		public IList GetTaskList()
		{
			using(ISession session = _sessionManager.OpenSession())
			{
				try
				{
					string actors = "'"+this.CurrentUser.Identity.Name+"'";
					bool is_only = true;
			
					foreach(string role in Configuration.RoleGroups)
					{
						if (this.CurrentUser.IsInRole(role))
						{
							actors += ",'" + role+"'";
							is_only = false;
						}
					}

					string sql = "SELECT ID FROM dbo.NBPM_FLOW ";
					if (is_only)
						sql += "WHERE ACTORID = "+actors;
					else
						sql += "WHERE ACTORID in ("+actors+")";

					DataTable flows = BEGDC.Utility.NHibernate.NHibernateUtil.Execute(session, sql);

//					sql = "SELECT dbo.Demo.NBPMFlow as NBPMFlow "+
//						" FROM dbo.Demo INNER JOIN "+
//						" dbo.ProjectMember ON "+
//						" dbo.Project.ProjectID = dbo.ProjectMember.ProjectID INNER JOIN "+
//						" dbo.CODMRole ON dbo.ProjectMember.RoleID = dbo.CODMRole.RoleID INNER JOIN "+
//						" dbo.Employee ON  dbo.ProjectMember.EmployeeID = dbo.Employee.EmployeeID "+
//						" WHERE (dbo.CODMRole.Name = '"+WorkflowRoles.AQEngineer+"') AND "+
//						" (dbo.Employee.ADName = '"+this.CurrentUser.Identity.Name+"') AND (dbo.Project.ProjectStatus = '"+WorkTransition.TQPQAQReport+"')";
//					DataTable projectflows = BEGDC.Utility.NHibernate.NHibernateUtil.Execute(session, sql);

					long[] flowids = new long[flows.Rows.Count/*+projectflows.Rows.Count*/];

					for(int i=0; i<flows.Rows.Count; i++)
						flowids[i] = (long)(flows.Rows[i][0]);
//					for(int i=0; i<projectflows.Rows.Count; i++)
//						flowids[flows.Rows.Count+i] = (long)(projectflows.Rows[i][0]);
					
					return flowids;
				}
				catch(Exception exp)
				{
					throw exp;
				}
				finally
				{
					session.Close();
				}						
			}
		}

		#endregion

		private void Perform(long flowID, IDictionary attributes)
		{
			IExecutionSessionLocal executionComponent = null;
			try
			{
				executionComponent = ServiceLocator.Instance.GetService(typeof (IExecutionSessionLocal)) as IExecutionSessionLocal;	
				
				string statusflag = BEGDC.CC.BL.Common.SysDicItem.ProjectStatusFlag.NORMAL;
				
				IList flows = null;
				if (attributes != null)
				{
					flows = executionComponent.PerformActivity(flowID, attributes);
					string step = (string)attributes[NEXT_TRANSITION];
					if (step != BEGDC.CC.BL.Workflow.WorkTransition.Submit)
						statusflag = BEGDC.CC.BL.Common.SysDicItem.ProjectStatusFlag.QUERY;
				}
				else
					flows = executionComponent.PerformActivity(flowID);

				string status = BEGDC.CC.BL.Workflow.WorkTransition.End;
				string owner = "N/A";
				

				if (flows.Count > 0)
				{
					IFlow flow = (IFlow)flows[0];
					status = flow.Node.Name;
					Type curtype = flow.Node.GetType();
					Type endtype = typeof(NetBpm.Workflow.Definition.Impl.EndStateImpl);
					if (curtype.Equals(endtype) || curtype.IsSubclassOf(endtype))
						owner = "N/A";
					else
						owner = flow.GetActor().Name;
				}

				//Update Project Status
				using(ISession session = _sessionManager.OpenSession())
				{
					try
					{
//						if (status != BEGDC.CC.BL.Workflow.WorkTransition.End)
//						{
//							string sql = "Update Demo Set DemoStatus='"+status+ "',StatusFlag='"+statusflag+"' Where NBPMFlow="+flowID.ToString();
//							BEGDC.Utility.NHibernate.NHibernateUtil.ExecuteNonQuery(session, sql);
//
////							sql = "Update Change Set ChangeStatus='"+status+"' Where NBPMFlow="+flowID.ToString();
////							BEGDC.Utility.NHibernate.NHibernateUtil.ExecuteNonQuery(session, sql);
//						}
//						else
//						{
//							statusflag = BEGDC.CC.BL.Common.SysDicItem.ProjectStatusFlag.NORMAL;
//						
//							string sql = "Update Demo Set DemoStatus='"+status+ "',StatusFlag='"+statusflag+"' Where NBPMFlow="+flowID.ToString();
//							BEGDC.Utility.NHibernate.NHibernateUtil.ExecuteNonQuery(session, sql);
//
////							sql = "Update Change Set ChangeStatus='"+status+"',EndTime='"+DateTime.Now.ToString()+"' Where NBPMFlow="+flowID.ToString();
////							BEGDC.Utility.NHibernate.NHibernateUtil.ExecuteNonQuery(session, sql);
//						}
					}
					catch(Exception exp)
					{
						throw exp;
					}
					finally
					{
						session.Close();
					}						
				}
				
			}
			catch(Exception ex)
			{
				throw new GDCException(WorkflowErrorCode.EXEC_PERFORM, "Execute flow("+flowID.ToString()+") error.", ex);
			}
			finally
			{
				ServiceLocator.Instance.Release(executionComponent);
			}
		}


		private void PerformTS( long flowID, IDictionary attributes)
		{
			IExecutionSessionLocal executionComponent = null;
			try
			{
				executionComponent = ServiceLocator.Instance.GetService(typeof (IExecutionSessionLocal)) as IExecutionSessionLocal;	
				
				string statusflag = BEGDC.CC.BL.Common.SysDicItem.ProjectStatusFlag.NORMAL;
				
				IList flows = null;
				if (attributes != null)
				{
					flows = executionComponent.PerformActivity(flowID, attributes);
					string step = (string)attributes[NEXT_TRANSITION];
					if (step != BEGDC.CC.BL.Workflow.WorkTransition.Submit)
						statusflag = BEGDC.CC.BL.Common.SysDicItem.ProjectStatusFlag.QUERY;
				}
				else
					flows = executionComponent.PerformActivity(flowID);

				string status = BEGDC.CC.BL.Workflow.WorkTransition.End;
//				string owner = "N/A";
//				
//
				if (flows.Count > 0)
				{
					IFlow flow = (IFlow)flows[0];
					status = flow.Node.Name;
//					Type curtype = flow.Node.GetType();
//					Type endtype = typeof(NetBpm.Workflow.Definition.Impl.EndStateImpl);
//					if (curtype.Equals(endtype) || curtype.IsSubclassOf(endtype))
//						owner = "N/A";
//					else
//						owner = flow.GetActor().Name;
				}

//				//Update TS Status
//				using(ISession session = _sessionManager.OpenSession())
//				{
//					try
//					{
//						if (status != BEGDC.CC.BL.Workflow.WorkTransition.End)
//						{
//							string sql = "Update TSRecord Set TSStatus='"+status+"', StatusFlag='"+statusflag+"' Where NBPMFlow="+flowID.ToString();
//							BEGDC.Utility.NHibernate.NHibernateUtil.ExecuteNonQuery(session, sql);
//						}
//						else
//						{
//							statusflag = BEGDC.CC.BL.Common.SysDicItem.ProjectStatusFlag.NORMAL;
//						
//							string sql = "Update TSRecord Set TSStatus='"+status+"', StatusFlag='"+statusflag+"',EndTime='"+DateTime.Now.ToString()+"' Where NBPMFlow="+flowID.ToString();
//							BEGDC.Utility.NHibernate.NHibernateUtil.ExecuteNonQuery(session, sql);
//						}
//					}
//					catch(Exception exp)
//					{
//						throw exp;
//					}
//					finally
//					{
//						session.Close();
//					}
//				}	
	
			}
			catch(Exception exp)
			{
				throw exp;
			}
			finally
			{
			}		
		}

		/// <summary>
		/// 
		/// </summary>
		public IPrincipal CurrentUser
		{
			get
			{
				return System.Web.HttpContext.Current.User;
			}
		}
	}
}
